/**
 * 主要思想： 将原型链继承和借用构造函数继承组合在一块，
 *          使用原型链实现对原型属性和方法的继承，
 *          使用构造函数来实现对实例属性的继承，
 *          这样就既通过在原型上定义方法来实现函数复用，又保证了每个实例都有自己的属性
 * 优点：
 *      1. 可以向超类型传递参数
 *      2. 每个实例都有自己的属性
 *      3. 实现了函数复用
 * 缺陷：
 *      1. 无论什么情况下，都会调用两次超类型构造函数：第一次是在创建子类型原型的时候，第二次是在创建实例时，在子类型构造函数内部
 * 
 * 当第一次调用 SuperType 构造函数时，SubType.prototype 会得到两个属性： name 和 colors；它们都是 SuperType 的实例属性。
 * 当调用 SubTpye 构造函数时，又会调用一次 SuperType 的构造函数，这一次在新对象上创建了 name 和 colors 属性，屏蔽了原型中同名的两个属性。
 */
function SuperType (name) {
  this.name = name,
  this.colors = ['green', 'blue']
}

function SubType (name, age) {
  SuperType.call(this, name)
  this.age = age
}

SubType.prototype = new SuperType()
SubType.prototype.constructor = SuperType
SubType.prototype.sayAge = function () {
  console.log(this.age)
}
SubType.prototype.sayName = function () {
  console.log(this.name)
}

const instance1 = new SubType('Yeoman', 21)
instance1.colors.push('yellow')
console.log(instance1.colors)
instance1.sayAge()
instance1.sayName()

const instance2 = new SubType('LYM', 18)
console.log(instance2.colors)
instance2.sayAge()
instance2.sayName()
